package com.ljh.localmusic.ui.component

import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Forward10
import androidx.compose.material.icons.filled.Image
import androidx.compose.material.icons.filled.PauseCircle
import androidx.compose.material.icons.filled.PlayCircle
import androidx.compose.material.icons.filled.Replay10
import androidx.compose.material.icons.filled.SkipNext
import androidx.compose.material.icons.filled.SkipPrevious
import androidx.compose.material.icons.rounded.MusicNote
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Slider
import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.ljh.localmusic.data.local.models.AudioItem
import com.ljh.localmusic.utils.ext.logd
import com.ljh.localmusic.utils.ext.loge
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds

/**
 * author：LJH on 2025/8/16 16:25
 *
 */
@Composable
fun MusicItemComponent(
    modifier: Modifier = Modifier,
    audioItem: AudioItem,
    imageUrl: String,
    currentPosition: Long,
    isPlaying: Boolean = false,
    refreshAiImage: () -> Unit = {},
    playPause: () -> Unit = {},
    previous: () -> Unit = {},
    next: () -> Unit = {},
    forward: () -> Unit = {},
    backward: () -> Unit = {},
) {

    // 1. 定义一个状态来持有当前要加载的图片模型 (Uri, String, 等)
    //    使用 `remember` 并以 primaryUri 和 fallbackImageUrl 为 key，
    //    这样当 AudioItem 变化时，状态会正确重置。
    var currentModel by remember(audioItem.artWork, imageUrl) {
        mutableStateOf(audioItem.artWork as Any?)
    }

    // 定义最终的、本地的错误占位图
    val finalErrorPainter = rememberVectorPainter(image = Icons.Rounded.MusicNote)

    val context = LocalContext.current
    // 2. 构建 ImageRequest，并附加上我们的自定义逻辑
    val imageRequest = remember(audioItem.artWork,imageUrl,currentModel) {
        ImageRequest.Builder(context)
            .data(currentModel) // 加载当前状态的模型
            .listener(
                onError = { _, result ->
                    "加载失败: ${result.throwable}".loge(tr = result.throwable)
                    // 3. 关键逻辑：检查失败的是不是主URI
                    //    并且备用URL是存在的
                    if (currentModel == audioItem.artWork && imageUrl.isNotBlank()) {
                        "主URI加载失败，尝试加载备用网络图片...,imageUrl: $imageUrl".logd()
                        // 如果是，将模型切换到备用URL，这将触发重组和新的加载请求
                        currentModel = imageUrl
                    }
                }
            )
            .build()
    }

    Column(
        modifier = modifier
            .fillMaxSize()
            .statusBarsPadding()
            .padding(horizontal = 20.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Spacer(modifier = Modifier.weight(1f))
        Spacer(modifier = Modifier.height(30.dp))
        if (audioItem.artWork != null){
            AsyncImage(
                model = imageRequest,
                error = finalErrorPainter,
                contentDescription = null,
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .sizeIn(maxWidth = 360.dp, maxHeight = 360.dp)
                    .aspectRatio(1f)
                    .clip(RoundedCornerShape(10.dp))
                    .weight(10f)
                    .clickable{
                        refreshAiImage()
                    }
            )
//            Image(
//                bitmap = audioItem.artWork.asImageBitmap(),
//                contentDescription = null,
//                contentScale = ContentScale.Crop,
//                modifier = Modifier
//                    .sizeIn(maxWidth = 360.dp, maxHeight = 360.dp)
//                    .aspectRatio(1f)
//                    .clip(RoundedCornerShape(10.dp))
//                    .weight(10f)
//            )
        } else {
            if (imageUrl.isNotEmpty()){
                AsyncImage(
                    modifier = Modifier
                        .sizeIn(maxWidth = 360.dp, maxHeight = 360.dp)
                        .aspectRatio(1f)
                        .clip(RoundedCornerShape(10.dp))
                        .weight(10f)
                        .clickable{
                            refreshAiImage()
                        },
                    model = imageUrl,
                    error = finalErrorPainter,
                    contentScale = ContentScale.Crop,
                    contentDescription = null
                )
            } else {
                Image(
                    imageVector = Icons.Default.Image,
                    contentDescription = null,
                    contentScale = ContentScale.Crop,
                    modifier = Modifier
                        .sizeIn(maxWidth = 360.dp, maxHeight = 360.dp)
                        .aspectRatio(1f)
                        .clip(RoundedCornerShape(10.dp))
                        .weight(10f)
                        .clickable{
                            "点击了".logd()
                            refreshAiImage()
                        }
                )
            }


        }
        Spacer(Modifier.height(30.dp))
        SongDescription(
            title = audioItem.title,
            name = audioItem.artist
        )
        Spacer(Modifier.height(30.dp))
        Column(
            modifier = Modifier.weight(10f)
        ) {
            PlayerSlider(
                ofSeconds = audioItem.duration.seconds,
                currentPosition = currentPosition,
            )
            Spacer(modifier = Modifier.height(40.dp))
            MusicPlayerButtons(
                isPlaying = isPlaying,
                playPause = playPause,
                previous = previous,
                next = next,
                forward = forward,
                backward = backward
            )
        }
        Spacer(
            modifier = Modifier.weight(1f)
        )

    }

}


@Composable
fun SongDescription(
    title: String,
    name: String
) {

    Text(
        text = title,
        style = MaterialTheme.typography.titleLarge,
        maxLines = 1,
        overflow = TextOverflow.Ellipsis,
        color = Color.White,
        fontWeight = FontWeight.Bold
    )
    Text(
        text = name,
        style = MaterialTheme.typography.titleMedium,
        maxLines = 1,
        overflow = TextOverflow.Ellipsis,
        color = Color.White.copy(0.7f)
    )


}

@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun PlayerSlider(
    ofSeconds: Duration?,
    currentPosition: Long = 0,
) {

    val durationFormat by remember(ofSeconds) {
        derivedStateOf {
            convertTimestampToDuration(ofSeconds?.inWholeSeconds ?: 0)
        }
    }

    val currentPositionFormat by remember(currentPosition) {
        derivedStateOf {
            convertTimestampToDuration(currentPosition)
        }
    }


    Column {
        Slider(
            value = currentPosition.toFloat(),
            valueRange = 0f..ofSeconds?.inWholeSeconds?.toFloat()!!,
            onValueChange = {

            },
            colors = SliderDefaults.colors(
                thumbColor = Color.White,
                activeTrackColor = Color.White,
                inactiveTrackColor = Color.White.copy(0.5f)
            )
        )
        Row(
            modifier = Modifier.fillMaxWidth()
        ) {
            Text(
                currentPositionFormat,
                style = MaterialTheme.typography.labelLarge,
                color = Color.White,
            )
            Spacer(modifier = Modifier.weight(1f))
            Text(
                text = durationFormat,
                color = Color.White,
                style = MaterialTheme.typography.labelLarge
            )
        }
    }
}


@Composable
fun MusicPlayerButtons(
    modifier: Modifier = Modifier,
    playerButtonSize: Dp = 72.dp,
    sideButtonSize: Dp = 42.dp,
    isPlaying: Boolean = false,
    playPause: () -> Unit = {},
    previous: () -> Unit = {},
    next: () -> Unit = {},
    forward: () -> Unit = {},
    backward: () -> Unit = {},
) {
//    val isPaused by remember { mutableStateOf(false) }
    var lifecycle by remember {
        mutableStateOf(Lifecycle.Event.ON_CREATE)
    }

    val lifecycleOwner = LocalLifecycleOwner.current
    DisposableEffect(lifecycleOwner) {
        val observer = LifecycleEventObserver{_,event, ->
            lifecycle = event
        }
        lifecycleOwner.lifecycle.addObserver(observer)

        onDispose {
            lifecycleOwner.lifecycle.removeObserver(observer)
        }
    }

    Row(
        modifier = modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceEvenly
    ) {
        val buttonModifier = Modifier
            .clip(CircleShape)
            .size(sideButtonSize)
            .semantics { role = Role.Button }

        Image(
            imageVector = Icons.Filled.SkipPrevious,
            contentDescription = "skip previous",
            contentScale = ContentScale.Fit,
            colorFilter = ColorFilter.tint(color = Color.White),
            modifier = buttonModifier.clickable{
                previous()
            }
        )
        Image(
            imageVector = Icons.Filled.Replay10,
            contentDescription = "skip previous",
            contentScale = ContentScale.Fit,
            colorFilter = ColorFilter.tint(color = Color.White),
            modifier = buttonModifier.clickable{
                backward()
            }
        )

        Image(
            imageVector = if (!isPlaying){
                Icons.Filled.PlayCircle
            } else {
                Icons.Filled.PauseCircle
            },
            contentDescription = "skip previous",
            contentScale = ContentScale.Fit,
            colorFilter = ColorFilter.tint(color = Color.White),
            modifier = Modifier
                .clip(CircleShape)
                .size(playerButtonSize)
                .clickable {
                    playPause()
                }
                .semantics {
                    role = Role.Button
                }
        )

        Image(
            imageVector = Icons.Filled.Forward10,
            contentDescription = "skip previous",
            contentScale = ContentScale.Fit,
            colorFilter = ColorFilter.tint(color = Color.White),
            modifier = buttonModifier.clickable{
                forward()
            }
        )
        Image(
            imageVector = Icons.Filled.SkipNext,
            contentDescription = "skip next",
            contentScale = ContentScale.Fit,
            colorFilter = ColorFilter.tint(color = Color.White),
            modifier = buttonModifier.clickable{
                next()
            }
        )
    }
}